home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / hips / sources / tools / mainpeak.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-06  |  14.7 KB  |  560 lines

  1. /*
  2. @    MAINPEAK.C -- find main image objects.
  3. @
  4. @    Copyright (c) 1991    Jin, Guojun
  5. @
  6. @ Usage:
  7. @    mainpeak [-lmuw#] [-LnU#] [-M [#]] [-O#] [-p#] [-z] [-F] [-a] [-c] [-e]
  8. @        [-fu] [<] infilename [> [-o] filename]                */
  9.  
  10. char    usage[]="Options\n\
  11. -F    force same format of output as input. Default output BYTE format.\n\
  12.     Inputs are in BYTE, SHORT, LONG(INT), and FLOAT formats\n\
  13. -M    Display all important information.\n\
  14. -g|d #    to reset good or bad range.\n\
  15. -a    do automatical adjustment.\n\
  16. -c[#]    clip top value down to 0 or [#] for non_BYTE format;\n\
  17.     if a number [#] given, it must follow -c without space.\n\
  18. -e    for preprocessed or enhanced image to adjust good and bad range.\n\
  19. -fu    FITS unix type\n\
  20. -L|U #    shift to #th Lower or Upper object.\n\
  21. -n #    output # peaks from lower one.\n\
  22. -O #    Offset for both ends. This convenient way to increase image range. \n\
  23. -p #    maximum peaks for one frame. Default is 48 for BYTE; 192 for SHORT &\n\
  24.     768 for LONG. When message \"There are more than xxx peaks in frame #\"\n\
  25.     given and picture is not satisfied, use this option to increase the\n\
  26.     peak bins to get more peaks.    \n\
  27. -lmu #    lower, middle & upper threshold value for frequency domain.    \n\
  28. -w #    hill foot width. default is 0 -- find widest one. Good value is > 256.\n\
  29. -z    count zero value.    \n\
  30. -o    option is used for PC kind computer which requires binary output\n\
  31.     file modes. No space allowed between switch and filename.    \n\
  32. [<] input [> output]\n", Dsrp[384], mbuf[128];
  33. /*
  34. @ compile: cc -O -o mainpeak mainpeak.c -lscs3 -lccs -lhips -lrle -ltiff -lm
  35. @
  36. @ AUTHOR:    Guojun Jin - Lawrence Berkeley Laboratory    1/22/91
  37. */
  38.  
  39. #include "header.def"
  40. #include "imagedef.h"
  41. #include <math.h>
  42.  
  43. U_IMAGE    uimg;
  44.  
  45. #define    ipxl_bytes    uimg.pxl_in
  46. #define    cln    uimg.width
  47. #define    row    uimg.height
  48. #define    frm    uimg.frames
  49.  
  50. #define    GValue(frp)    arget(argc, argv, &i, &frp)
  51.  
  52. #ifndef    GoodRange    /* used for find correct object spatial    domain    */
  53. #define    GoodRange    512
  54. #endif
  55. #ifndef    BadRange
  56. #define    BadRange    48
  57. #endif
  58. #ifndef    MOSTPEAKS    /* most peaks = MOSTPEAKS * pixel_bytes ^ 2    */
  59. #define    MOSTPEAKS    48
  60. #endif
  61.  
  62. typedef    struct    {    /* to store each peak's information    */
  63.     int    lower_p, upper_p,
  64.         peak_p, peak_v;    /* pos & value */
  65.     } Peak;
  66.  
  67. typedef    struct    {    /* system control block    */
  68.     int    nclip, nsp, objects,
  69.         hillfoot_w, doffset,
  70.         l_u, lp, rp,
  71.         lower, upper, width, p;
  72.     Peak*    s_array;
  73.     } Info;
  74.  
  75. typedef    struct    {
  76.     int    l, m, u,
  77.         overf;
  78.     } Threshold;
  79.  
  80. #ifdef    _DEBUG_
  81. extern    int    debug;
  82. #endif
  83.  
  84. MType    frp, fsize,
  85.     goodrange=GoodRange,
  86.     badrange = BadRange;
  87. float    scale=1., fmin, fscale();
  88. Info    info = {255, 0}; /* stupid SUN cc compiler can not initialize in main */
  89. Threshold threshold = {5, 0};
  90. bool    Msg=0, Zf=0, adj=0, pre_enh=0;
  91.  
  92.  
  93. main(argc, argv)
  94. int    argc;
  95. char **    argv;
  96. {
  97. int    i, MostObjs=0;
  98. MType    *hist, maxhisv=256;
  99. VType    *buf;
  100.  
  101. format_init(&uimg, IMAGE_INIT_TYPE, HIPS, -1, *argv, "S20-1");
  102.  
  103. for (i=1; i<argc; i++)
  104.     if (*argv[i] == '-') {
  105.     frp = 1;
  106.     switch(argv[i][frp++])
  107.     {
  108.     case 'F':    uimg.o_form=-1;    break;
  109. #ifdef    _DEBUG_
  110.     case 'D':    debug++;    break;
  111. #endif
  112.     case 'a':    adj++;    break;
  113.     case 'b':    badrange = GValue(frp);    break;
  114.     case 'c':    info.nclip=GValue(frp);    break;
  115.     case 'e':    pre_enh++;    break;
  116. #ifdef    FITS_IMAGE
  117.     case 'f':{
  118. extern    int    FTy;    FTy = 'u';    break;
  119.     }
  120. #endif
  121.     case 'g':    goodrange = GValue(frp);
  122.         break;
  123.     case 'M':    if (argv[i][frp])
  124.                 Msg = atoi(argv[i]+frp);
  125.             else    Msg--;    break;
  126.     case 'L':    info.l_u = -GValue(frp);    break;
  127.     case 'U':    info.l_u =  GValue(frp);    break;
  128.     case 'n':    info.objects = GValue(frp);    break;
  129.     case 'O':    info.doffset = GValue(frp);    break;
  130.     case 'l':    threshold.l = GValue(frp);    break;
  131.     case 'm':    threshold.m = GValue(frp);    break;
  132.     case 'u':    threshold.u = GValue(frp);    break;
  133.     case 'p':    MostObjs = GValue(frp) - 1;    break;
  134.     case 'w':    info.hillfoot_w = GValue(frp);    break;
  135.     case 'z':    Zf++;    break;
  136.     case 'o':if (freopen(argv[i]+2, "wb", stdout))    break;
  137.         message("output file -- %s", argv[i]);
  138.     default:
  139. errout:        usage_n_options(usage, i, argv[i]);
  140.     }
  141.     }
  142.     else if (freopen(argv[i], "rb", stdin) != stdin)
  143.         syserr("input file -- %s", argv[i]);
  144. io_test(stdin_fd, goto    errout);
  145.  
  146. if ((*uimg.header_handle)(HEADER_READ, &uimg, 0, 0))
  147.     syserr("unknown image type");
  148. fsize = cln * row;
  149. if (ipxl_bytes == 2)
  150.     maxhisv <<= 8;
  151. else if(ipxl_bytes == 4)
  152.     maxhisv <<= 10;    /* may use 12 - 16 for some reason */
  153. if (uimg.o_form < 0)
  154.     uimg.o_form = uimg.in_form,
  155.     uimg.pxl_out = uimg.pxl_in;
  156. else    uimg.o_form = IFMT_BYTE,
  157.     uimg.pxl_out = 1;
  158.  
  159. if (!MostObjs)    MostObjs = MOSTPEAKS * ipxl_bytes * ipxl_bytes;
  160. if (!threshold.m)
  161.     threshold.m = fsize / ((row + cln)*ipxl_bytes);
  162. while (threshold.m <= threshold.l)
  163.     threshold.m += threshold.l / ipxl_bytes;
  164. if (!threshold.u)
  165.     threshold.u = (1 << 31) - 1;
  166. else if (threshold.u < threshold.m)
  167.     threshold.u += threshold.m;
  168. if (pre_enh){
  169.     goodrange <<= ipxl_bytes;
  170.     badrange <<= ipxl_bytes;
  171.     threshold.m >>= 1;
  172. }
  173.  
  174. if(Msg)    message("l_threshold=%d, m_threshold=%d, u_threshold=%d, maxhv=%d\n",
  175.         threshold.l, threshold.m, threshold.u, maxhisv);
  176. if (uimg.in_type != HIPS){
  177. register int    mo_form = uimg.o_form, mo_pxl = uimg.pxl_out;
  178.     if (uimg.in_type == FITS)
  179.         uimg.o_form = uimg.in_form,    uimg.pxl_out = uimg.pxl_in;
  180.     (*uimg.std_swif)(FI_LOAD_FILE, &uimg, uimg.load_all=uimg.frames, No);
  181.     uimg.o_form = mo_form,    uimg.pxl_out = mo_pxl;
  182. }
  183. else    buf = uimg.src = nzalloc(fsize, ipxl_bytes, "buf");
  184.  
  185. hist = zalloc(maxhisv, (MType)sizeof(*hist), "hist");
  186. uimg.dest = uimg.src;
  187.  
  188. for (frp=0; frp<frm; frp++){
  189.     if (uimg.in_type != HIPS)
  190.         buf = (byte *) uimg.src + frp * fsize;
  191.     else    (*uimg.std_swif)(FI_LOAD_FILE, &uimg, uimg.load_all=0, No);
  192.     switch(uimg.in_form){
  193.     case IFMT_BYTE:
  194.         b_get_hist(buf, hist);
  195.         spectrum(hist, maxhisv, MostObjs, &threshold, &info);
  196.         i = widest_sp(&info, maxhisv);
  197.         if (i)    b_clip(buf, info.lp, info.rp);
  198.         break;
  199.     case IFMT_SHORT:
  200.         s_get_hist(buf, hist);
  201.         spectrum(hist, maxhisv, MostObjs, &threshold, &info);
  202.         i = widest_sp(&info, maxhisv);
  203.         if (i)    s_clip(buf, info.lp, info.rp, info.nclip);
  204.         break;
  205.     case IFMT_LONG:
  206.         i_get_hist(buf, hist);
  207.         spectrum(hist, maxhisv, MostObjs, &threshold, &info);
  208.         i = widest_sp(&info, maxhisv);
  209.         if (i)    i_clip(buf, info.lp, info.rp, info.nclip);
  210.         break;
  211.     case IFMT_FLOAT:
  212.         scale = 1. / fscale(buf, maxhisv, &fmin);
  213.         i_get_hist(buf, hist);
  214.         spectrum(hist, maxhisv, MostObjs, &threshold, &info);
  215.         i = widest_sp(&info, maxhisv);
  216.         if (i)    i_clip(buf, info.lp, info.rp, info.nclip);
  217.         break;
  218.     default:syserr("unaccept format %d", uimg.in_form);
  219.     }
  220.     if (!i)    msg("no object found in frame(%d)", frp);
  221.     if (uimg.in_form != uimg.o_form)
  222.         tobyte(buf, ipxl_bytes);
  223.     else if (uimg.o_form == IFMT_FLOAT)
  224.         itof(buf);
  225.     if (frp==0){
  226.         (*uimg.header_handle)(ADD_DESC, &uimg, Dsrp);
  227.         (*uimg.header_handle)(HEADER_WRITE, &uimg, argc, argv, True);
  228.     }
  229.     (*uimg.std_swif)(FI_SAVE_FILE, &uimg, buf, uimg.save_all=0);
  230.     for (i=0; i<maxhisv; i++)    hist[i]=0;
  231. }
  232. exit(0);
  233. }
  234.  
  235. /*======================================*
  236. *    find histgram for each frame    *
  237. *======================================*/
  238. b_get_hist(ibp, hstp)
  239. register byte*    ibp;
  240. register int*    hstp;
  241. {
  242. register int    i;
  243. for (i=0; i<fsize; i++)    hstp[*ibp++]++;
  244. }
  245.  
  246. s_get_hist(ibp, hstp)
  247. register unsigned short    *ibp;
  248. register int*    hstp;
  249. {
  250. register int    i;
  251. for (i=0; i<fsize; i++)    hstp[*ibp++]++;
  252. }
  253.  
  254. i_get_hist(ibp, hstp)
  255. register int*    ibp, *hstp;
  256. {
  257. register int    i;
  258. for (i=0; i<fsize; i++)    hstp[*ibp++]++;
  259. }
  260.  
  261. /*======================================*
  262. *    discard unwanted objects    *
  263. *======================================*/
  264. b_clip(bp, lp, rp)
  265. register byte*    bp;
  266. register int    lp, rp;
  267. {
  268. register int    i;
  269.  
  270. for (i=0; i<fsize; i++, bp++)
  271.     if (*bp < lp)    *bp = lp;
  272.     else if (*bp > rp)    *bp = rp;
  273. }
  274.  
  275. s_clip(bp, lp, rp, top)
  276. register unsigned short    *bp;
  277. register int    lp, rp, top;
  278. {
  279. register int    i;
  280.  
  281. for (i=0; i<fsize; i++, bp++)
  282.     if (*bp < lp)    *bp = lp;
  283.     else if (*bp > rp)    *bp = top;
  284. }
  285.  
  286. i_clip(bp, lp, rp, top)
  287. register unsigned*    bp;
  288. register int    lp, rp, top;
  289. {
  290. register int    i;
  291.  
  292. for (i=0; i<fsize; i++, bp++)
  293.     if (*bp < lp)    *bp = lp;
  294.     else if (*bp > rp)    *bp = top;
  295. }
  296.  
  297.  
  298. /*======================================================*
  299. *    find group of hills in a frame            *
  300. *    peak_v < pixel_number/((r+c) * bytes_per_pixel)    *
  301. *    valley => 5 is suggested (range 1 - ...)    *
  302. *======================================================*/
  303. spectrum(buf, bwidth, sets, tp, ip)
  304. MType    *buf, bwidth;
  305. int    sets;
  306. Threshold*    tp;
  307. Info*    ip;
  308. {
  309. register MType    hp = -1, ap;
  310. Peak*    array=zalloc(sizeof(*array), sets);
  311.  
  312. if (!Zf)    *buf = 0;    /* reset zero's value    */
  313. else    msg("zeros = %d\n", *buf);
  314. while (!buf[++hp]);    /* find lowest bound */
  315. if (scale==1. && !fmin)
  316.     sprintf(Dsrp, "%d -- ", hp);
  317. else    sprintf(Dsrp, "%f -- ", hp*scale+fmin);
  318.  
  319. for (ap=0; hp<bwidth && ap < sets; hp++){
  320. register int    hval;
  321.     hval = buf[hp];
  322.     /*    find widest unthreshold body for adjusting    */
  323.     if (hval && !ip->lower)    ip->lower = hp;
  324.     else if (!hval && ip->lower){
  325.         ip->upper = hp;
  326.         if (ip->upper - ip->lower > ip->width)
  327.             ip->width = ip->upper - ip->lower;
  328.         ip->lower = 0;
  329.     }
  330.     /* CALC spectrums.    If over lower threshold    */
  331.     if (hval > tp->l){
  332.         if (!array[ap].lower_p)
  333.             array[ap].lower_p = hp;    /* get entrance    */
  334.         if (hval > tp->u)
  335.             tp->overf++;
  336.         if (hval > tp->m && hval > array[ap].peak_v){
  337.             array[ap].peak_p = hp;    /* get peak point    */
  338.             array[ap].peak_v = hval;
  339.         }
  340.     }/*    ELSE if lower than threshold    */
  341.     else if (array[ap].lower_p)
  342.         if (array[ap].peak_v && !tp->overf)    /* if passed or had peak    */
  343.             array[ap++].upper_p = hp;    /* get exit    */
  344.         else    /* reset entrance    */
  345.             array[ap].lower_p=array[ap].peak_v=tp->overf=0;
  346. }
  347. if (array[ap].peak_v && !array[ap].upper_p)
  348.     array[ap++].upper_p = hp;
  349. if(ap){
  350.     ip->s_array = zalloc((MType)ap, (MType)sizeof(*array));
  351.     memcpy(ip->s_array, array, ap*sizeof(*array));
  352. }
  353. free(array);
  354. if (scale==1. && !fmin)
  355.     sprintf(mbuf, "%d: ", ip->upper);
  356. else    sprintf(mbuf, "%f: ", ip->upper*scale+fmin);
  357. strcat(Dsrp, mbuf);
  358. ip->lower = ip->upper - ip->width;
  359. spectrum_dump(ip->s_array, ap, Msg);
  360. if (hp == bwidth)
  361.     sprintf(mbuf, "Total %d Distinguishable", ap);
  362. else    sprintf(mbuf, "There are more than %d", ap);
  363. strcat(Dsrp, mbuf);
  364. sprintf(mbuf, " Peak(s) in frame %d\n", frp+1);
  365. strcat(Dsrp, mbuf);
  366. mesg(Dsrp);
  367. ip->nsp = ap;
  368. }
  369.  
  370. spectrum_dump(array, nsp, nMsg)
  371. Peak*    array;
  372. unsigned    nsp, nMsg;
  373. {
  374. unsigned    i, j=MIN(nsp,nMsg);
  375. for (i=0; i<j; i++, array++)
  376.     message("PEAK%02d: lp->%d : up->%d |=| pp->%d : pv->%d\n", i+1,
  377.         array->lower_p, array->upper_p, array->peak_p, array->peak_v);
  378. }
  379.  
  380.  
  381. /*======================================================*
  382. *    find peaks which satisfy the conditions set    *
  383. *    in infomation structure. If the peak bottom    *
  384. *    smaller than condition & no more objects    *
  385. *    specified, this program will try to find a    *
  386. *    good range to display the main image.        *
  387. *======================================================*/
  388. bool    widest_sp(IFp, Top)
  389. register Info*    IFp;
  390. MType    Top;
  391. {
  392. register Peak*    spp = IFp->s_array;
  393. register int    i, tmp, maxw=spp->upper_p - spp->lower_p;
  394. int    sp=0;
  395.  
  396. for (i=1; i<IFp->nsp; i++){
  397.     spp++;
  398.     tmp = spp->upper_p - spp->lower_p;
  399.     if (maxw < tmp){
  400.         maxw = tmp;    sp=i;
  401.     }
  402. }
  403. if (!IFp->hillfoot_w && maxw < badrange && !IFp->objects){
  404.     if (Msg) {
  405.         sprintf(mbuf, "parameter automtically adjusted: brange=%d, grange=%d\n",
  406.             badrange, goodrange);
  407.         strcat(Dsrp, mbuf);
  408.         mesg(mbuf);
  409.     }
  410.     if (adj && IFp->width > maxw)
  411.         sp = IFp->lower;
  412.     sp += IFp->l_u;
  413.     if (sp < 0)    sp = 0;
  414.     else if (sp > IFp->nsp)
  415.         sp = IFp->nsp-1;
  416.     if (maxw==1 && !sp)    /* for large spread, start from middle */
  417.         sp = IFp->nsp >> 1;
  418.     IFp->lp = IFp->s_array[tmp=sp].lower_p;
  419.  
  420.     if (scale==1. && !fmin)
  421.         sprintf(mbuf, "Base: width = %d(%d -- %d), sp=%d\n", maxw,
  422.         IFp->s_array[tmp].lower_p, IFp->s_array[tmp].upper_p, sp);
  423.     else sprintf(mbuf, "Base: width = %.4f(%.4f -- %.4f), sp=%d\n",
  424.         maxw*scale, IFp->s_array[tmp].lower_p*scale+fmin,
  425.         IFp->s_array[tmp].upper_p*scale+fmin, sp);
  426.     strcat(Dsrp, mbuf);
  427.     mesg(mbuf);
  428.  
  429.     {
  430.     register int    offset=0;
  431.         while (maxw < goodrange && (tmp || sp < IFp->nsp)){
  432.         if(tmp)    {    /* lower bound check */
  433.             tmp--;
  434.             if (pre_enh && IFp->lp - IFp->s_array[tmp].upper_p > badrange)
  435. #ifdef    SOMEHOW
  436.                 offset += IFp->lp-IFp->s_array[tmp].upper_p+badrange;
  437. #else
  438.                 offset += badrange;
  439. #endif
  440.             IFp->lp = IFp->s_array[tmp].lower_p;
  441.         }
  442.         if(sp<IFp->nsp){/* upper bound check */
  443.             if (pre_enh && IFp->rp)
  444.             if (IFp->s_array[sp].lower_p - IFp->rp > badrange)
  445. #ifdef    SOMEHOW
  446.                 offset += IFp->s_array[sp].lower_p-IFp->rp+badrange;
  447. #else
  448.                 offset += badrange;
  449. #endif
  450.             IFp->rp = IFp->s_array[sp++].upper_p;
  451.         }
  452.         maxw = IFp->rp - IFp->lp - offset;
  453.         }
  454.     }
  455.     IFp->objects = sp-- - ++tmp;
  456. }
  457. else{
  458.     tmp = sp + IFp->l_u;
  459.     if (tmp + IFp->objects >= IFp->nsp)
  460.         tmp = IFp->nsp-1-IFp->objects;
  461.     if (tmp < 0){    tmp = 0;    IFp->objects = sp;    }
  462.     else if(tmp >= IFp->nsp)
  463.         {    tmp = IFp->nsp-1;    IFp->objects=1;    }
  464.     IFp->lp = IFp->s_array[tmp].lower_p;
  465.     IFp->rp = IFp->s_array[tmp++ + IFp->objects].upper_p;
  466. }
  467. IFp->lp -= IFp->doffset;
  468. if (IFp->lp < 0)    IFp->lp = 0;
  469. IFp->rp += IFp->doffset;
  470. if (IFp->rp > Top)    IFp->rp = Top;
  471. if (IFp->nclip)    IFp->nclip=IFp->rp;
  472. if (scale==1. && !fmin)
  473.     sprintf(mbuf, "Output from #%d to #%d bandwidth %d--%d\n",
  474.     tmp, IFp->objects+tmp, IFp->lp, IFp->rp);
  475. else sprintf(mbuf, "Output from #%d to #%d bandwidth %.4f--%.4f\n",
  476.     tmp, IFp->objects+tmp, IFp->lp*scale+fmin, IFp->rp*scale+fmin);
  477. strcat(Dsrp, mbuf);
  478. mesg(mbuf);
  479. return    (maxw >= IFp->hillfoot_w);
  480. }
  481.  
  482.  
  483. /*======================================*
  484. *    find the min & max for float    *
  485. *    & scale float to integer    *
  486. *======================================*/
  487. float    fscale(buf, maxfv, fmin)
  488. void    *buf;
  489. float    *fmin;
  490. {
  491. register int    i;
  492. register float    *bp=buf;
  493. register float    max = -3.4e38,
  494.         min = 3.4e38;
  495. for (i=0; i<fsize; i++, bp++)
  496.     if (*bp > max)    max = *bp;
  497.     else if (*bp < min)    min = *bp;
  498. #ifdef    _DEBUG_
  499.     message("Min=%f, Max=%f, ", min, max);
  500. #endif
  501.    {
  502.     register int*    ibp=buf;
  503.     max = maxfv / (max - min); /* around 1 MBYTE */
  504. #ifdef    _DEBUG_
  505.     msg("Scale=%f\n", max);    /* use max register as scale register */
  506. #endif
  507.     for (i=0, bp=buf; i<fsize; i++)
  508.         *ibp++ = (*bp++ - min) * max + 0.5;
  509.    }
  510. *fmin = min;
  511. return    max;    /* scale */
  512. }
  513.  
  514. tobyte(buf, ibytes)
  515. void    *buf;
  516. {
  517. register int    i;
  518.  
  519. if (ibytes == 2){    /*    short => integer convert    */
  520. register unsigned short    *sbp = buf, min=65535;
  521.    {    register unsigned short    max=0;
  522.     for (i=0; i<fsize; i++, sbp++)
  523.         if (*sbp > max)    max = *sbp;
  524.         else if (*sbp < min)    min = *sbp;
  525.     i = max - min;
  526.     if(Msg)    message("SHORT to BYTE (%d -- %d)\n", min, max);
  527.    }{
  528.     register float    scale = 255. / i;
  529.     register byte*    bp = buf;
  530.     for (i=0, sbp=buf; i<fsize; i++)
  531.         *bp++ = (*sbp++ - min) * scale + 0.5;
  532.    }
  533. }
  534. else{
  535. register int*    ibp = buf, min=1048575;
  536.    {    register int    max = -32768;
  537.     for (i=0; i<fsize; i++, ibp++)
  538.         if (*ibp > max)    max = *ibp;
  539.         else if (*ibp < min)    min = *ibp;
  540.     i = max - min;
  541.     if(Msg)    message("long to BYTE (%d -- %d)\n", min, max);
  542.    }{
  543.     register float    scale = 255. / i;
  544.     register byte*    bp = buf;
  545.     for (i=0, ibp=buf; i<fsize; i++)
  546.         *bp++ = (*ibp++ - min) * scale + 0.5;
  547.    }
  548. }
  549. }
  550.  
  551. itof(buf)
  552. void    *buf;
  553. {
  554. register int    *ip=buf, i;
  555. register float    *op=buf;
  556.  
  557. for (i=fsize; i--;)
  558.     *op++ = *ip++;
  559. }
  560.